//package sufutian.com.google_speech;
//
//import android.content.Context;
//import android.content.SharedPreferences;
//import android.os.AsyncTask;
//import android.util.Log;
//
//import com.google.auth.Credentials;
//import com.google.auth.oauth2.AccessToken;
//import com.google.auth.oauth2.GoogleCredentials;
//import com.google.cloud.speech.v1.LongRunningRecognizeRequest;
//import com.google.cloud.speech.v1.RecognitionAudio;
//import com.google.cloud.speech.v1.RecognitionConfig;
//import com.google.cloud.speech.v1.RecognizeRequest;
//import com.google.cloud.speech.v1.RecognizeResponse;
//import com.google.cloud.speech.v1.SpeechRecognitionAlternative;
//import com.google.cloud.speech.v1.SpeechRecognitionResult;
//import com.google.longrunning.Operation;
//import com.google.protobuf.Any;
//import com.google.protobuf.ByteString;
//
//import java.io.IOException;
//import java.io.InputStream;
//import java.net.URI;
//import java.net.URISyntaxException;
//import java.util.Collections;
//import java.util.Date;
//import java.util.List;
//import java.util.Map;
//
//import io.grpc.CallOptions;
//import io.grpc.Channel;
//import io.grpc.ClientCall;
//import io.grpc.ClientInterceptor;
//import io.grpc.ClientInterceptors;
//import io.grpc.ManagedChannel;
//import io.grpc.Metadata;
//import io.grpc.MethodDescriptor;
//import io.grpc.Status;
//import io.grpc.StatusException;
//import io.grpc.internal.DnsNameResolverProvider;
//import io.grpc.okhttp.OkHttpChannelProvider;
//import io.grpc.stub.StreamObserver;
//
///**
// * Created by sufutian on 2017/6/21.
// */
//
//public class EnglishVoiceClient {
//
//    /**
//     * 获取token
//     */
//    private volatile AccessTokenTask mAccessTokenTask;
//
//    private String TAG = "sufutian==";
//
//    private Context context;
//    /**
//     * sp name
//     */
//    private final String PREFS = "EnglishVoiceClient";
//    /**
//     * token name
//     */
//    private final String PREF_ACCESS_TOKEN_VALUE = "access_token_value";
//    /**
//     * sp存取token过期时间
//     */
//    private final String PREF_ACCESS_TOKEN_EXPIRATION_TIME = "access_token_expiration_time";
//    /**
//     * token过期时间
//     */
//    private final int ACCESS_TOKEN_EXPIRATION_TOLERANCE = 30 * 60 * 1000; // thirty minutes
//
//    private final int ACCESS_TOKEN_FETCH_MARGIN = 60 * 1000; // one minute
//    /**
//     * 谷歌证书范围
//     */
//    public final List<String> SCOPE =
//            Collections.singletonList("https://www.googleapis.com/auth/cloud-platform");
//    /**
//     * host
//     */
//    private static final String HOSTNAME = "speech.googleapis.com";
//    /**
//     * 端口
//     */
//    private static final int PORT = 443;
//    /**
//     * 谷歌语音api
//     */
//    private SpeechGrpc.SpeechStub mApi;
//
//
//    StreamObserver<Operation> resultObserver = new StreamObserver<Operation>() {
//        @Override
//        public void onNext(Operation operation) {
//            final String name = operation.getName();
//            Any metadata = operation.getMetadata();
//            buiness.getResult(name, "AIzaSyBqRkKbmeZ_7NIMSQWciT7-Y4bK1kwjnWQ");
//            Log.e(TAG, "onNext: " + name);
//        }
//
//        @Override
//        public void onError(Throwable t) {
//            Log.e(TAG, "onError: " + t.toString());
//        }
//
//        @Override
//        public void onCompleted() {
//            Log.e(TAG, "onCompleted: ");
//        }
//    };
//    private final SpeechBuiness buiness;
//
//
//    public EnglishVoiceClient(Context context) {
//        this.context = context;
//        buiness = new SpeechBuiness(context);
//        fetchAccessToken();
//    }
//
//    private void fetchAccessToken() {
//        if (mAccessTokenTask != null) {
//            return;
//        }
//        mAccessTokenTask = new AccessTokenTask();
//        mAccessTokenTask.execute();
//    }
//
//
//    private class AccessTokenTask extends AsyncTask<Void, Void, AccessToken> {
//
//        @Override
//        protected AccessToken doInBackground(Void... voids) {
//
//            final SharedPreferences prefs = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
//            String tokenValue = prefs.getString(PREF_ACCESS_TOKEN_VALUE, null);
//            long expirationTime = prefs.getLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME, -1);
//
//            // Check if the current token is still valid for a while
//            if (tokenValue != null && expirationTime > 0) {
//                if (expirationTime > System.currentTimeMillis() + ACCESS_TOKEN_EXPIRATION_TOLERANCE) {
//                    return new AccessToken(tokenValue, new Date(expirationTime));
//                }
//            }
//
//
//            // ***** WARNING *****
//            // In this sample, we load the credential from a JSON file stored in a raw resource
//            // folder of this client app. You should never do this in your app. Instead, store
//            // the file in your server and obtain an access token from there.
//            // *******************
//            final InputStream stream = context.getResources().openRawResource(R.raw.credential);
//            try {
//                final GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
//                        .createScoped(SCOPE);
//                final AccessToken token = credentials.refreshAccessToken();
//                Log.e(TAG, "doInBackground: token" + token);
//                prefs.edit()
//                        .putString(PREF_ACCESS_TOKEN_VALUE, token.getTokenValue())
//                        .putLong(PREF_ACCESS_TOKEN_EXPIRATION_TIME,
//                                token.getExpirationTime().getTime())
//                        .apply();
//
//                return token;
//            } catch (IOException e) {
//                Log.e(TAG, "Failed to obtain access token.", e);
//            }
//            return null;
//        }
//
//        @Override
//        protected void onPostExecute(AccessToken accessToken) {
//            mAccessTokenTask = null;
//            final ManagedChannel channel = new OkHttpChannelProvider()
//                    .builderForAddress(HOSTNAME, PORT)
//                    .nameResolverFactory(new DnsNameResolverProvider())
//                    .intercept(new GoogleCredentialsInterceptor(new GoogleCredentials(accessToken)
//                            .createScoped(SCOPE)))
//                    .build();
//            mApi = SpeechGrpc.newStub(channel);
//            Log.e(TAG, "onPostExecute: api建立");
//
//        }
//    }
//
//
//    /**
//     * Authenticates the gRPC channel using the specified {@link GoogleCredentials}.
//     */
//    private class GoogleCredentialsInterceptor implements ClientInterceptor {
//
//        private final Credentials mCredentials;
//
//        private Metadata mCached;
//
//        private Map<String, List<String>> mLastMetadata;
//
//        GoogleCredentialsInterceptor(Credentials credentials) {
//            mCredentials = credentials;
//        }
//
//        @Override
//        public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
//                final MethodDescriptor<ReqT, RespT> method, CallOptions callOptions,
//                final Channel next) {
//            return new ClientInterceptors.CheckedForwardingClientCall<ReqT, RespT>(
//                    next.newCall(method, callOptions)) {
//                @Override
//                protected void checkedStart(Listener<RespT> responseListener, Metadata headers)
//                        throws StatusException {
//                    Metadata cachedSaved;
//                    URI uri = serviceUri(next, method);
//                    synchronized (this) {
//                        Map<String, List<String>> latestMetadata = getRequestMetadata(uri);
//                        if (mLastMetadata == null || mLastMetadata != latestMetadata) {
//                            mLastMetadata = latestMetadata;
//                            mCached = toHeaders(mLastMetadata);
//                        }
//                        cachedSaved = mCached;
//                    }
//                    headers.merge(cachedSaved);
//                    delegate().start(responseListener, headers);
//                }
//            };
//        }
//
//
//        /**
//         * Generate a JWT-specific service URI. The URI is simply an identifier with enough
//         * information for a service to know that the JWT was intended for it. The URI will
//         * commonly be verified with a simple string equality check.
//         */
//        private URI serviceUri(Channel channel, MethodDescriptor<?, ?> method)
//                throws StatusException {
//            String authority = channel.authority();
//            if (authority == null) {
//                throw Status.UNAUTHENTICATED
//                        .withDescription("Channel has no authority")
//                        .asException();
//            }
//            // Always use HTTPS, by definition.
//            final String scheme = "https";
//            final int defaultPort = 443;
//            String path = "/" + MethodDescriptor.extractFullServiceName(method.getFullMethodName());
//            URI uri;
//            try {
//                uri = new URI(scheme, authority, path, null, null);
//            } catch (URISyntaxException e) {
//                throw Status.UNAUTHENTICATED
//                        .withDescription("Unable to construct service URI for auth")
//                        .withCause(e).asException();
//            }
//            // The default port must not be present. Alternative ports should be present.
//            if (uri.getPort() == defaultPort) {
//                uri = removePort(uri);
//            }
//            return uri;
//        }
//
//        private Map<String, List<String>> getRequestMetadata(URI uri) throws StatusException {
//            try {
//                return mCredentials.getRequestMetadata(uri);
//            } catch (IOException e) {
//                throw Status.UNAUTHENTICATED.withCause(e).asException();
//            }
//        }
//
//        private URI removePort(URI uri) throws StatusException {
//            try {
//                return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), -1 /* port */,
//                        uri.getPath(), uri.getQuery(), uri.getFragment());
//            } catch (URISyntaxException e) {
//                throw Status.UNAUTHENTICATED
//                        .withDescription("Unable to construct service URI after removing port")
//                        .withCause(e).asException();
//            }
//        }
//
//        private Metadata toHeaders(Map<String, List<String>> metadata) {
//            Metadata headers = new Metadata();
//            if (metadata != null) {
//                for (String key : metadata.keySet()) {
//                    Metadata.Key<String> headerKey = Metadata.Key.of(
//                            key, Metadata.ASCII_STRING_MARSHALLER);
//                    for (String value : metadata.get(key)) {
//                        headers.put(headerKey, value);
//                    }
//                }
//            }
//            return headers;
//        }
//    }
//
//    public void recognizeInputStream(final InputStream stream, final boolean longUPload) {
//        if (mApi == null) {
//            Log.e(TAG, "recognizeInputStream: api为null");
//            return;
//        }
//
//        new Thread() {
//            @Override
//            public void run() {
//
//                if (longUPload) {
//                    Log.e(TAG, "run: 长识别开始");
//                    try {
//                        mApi.longRunningRecognize(LongRunningRecognizeRequest.newBuilder()
//                                        .setConfig(RecognitionConfig.newBuilder()
//                                                .setEncoding(RecognitionConfig.AudioEncoding.LINEAR16)
//                                                .setLanguageCode("en-US")
//                                                .setSampleRateHertz(44100)
//                                                .build())
//                                        .setAudio(RecognitionAudio.newBuilder()
////                                                .setContent(ByteString.readFrom(stream))
//                                                .setUri("gs://goplay-1201.appspot.com/audio/sufutian.wav")
//                                                .build())
//                                        .build()
//                                , resultObserver);
////                        stream.close();
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                        Log.e(TAG, "长识别异常");
//                    }
//                } else {
//                    try {
//                        mApi.recognize(
//                                RecognizeRequest.newBuilder()
//                                        .setConfig(RecognitionConfig.newBuilder()
//                                                .setEncoding(RecognitionConfig.AudioEncoding.LINEAR16)
//                                                .setLanguageCode("en-US")
//                                                .setSampleRateHertz(44100)
//                                                .build())
//                                        .setAudio(RecognitionAudio.newBuilder()
//                                                .setContent(ByteString.readFrom(stream))
//                                                .build())
//                                        .build(),
//                                new StreamObserver<RecognizeResponse>() {
//                                    @Override
//                                    public void onNext(RecognizeResponse response) {
//                                        String text = null;
//                                        if (response.getResultsCount() > 0) {
//                                            final SpeechRecognitionResult result = response.getResults(0);
//                                            if (result.getAlternativesCount() > 0) {
//                                                final SpeechRecognitionAlternative alternative = result.getAlternatives(0);
//                                                text = alternative.getTranscript();
//
//                                            }
//                                        }
//                                        if (text != null) {
//
//                                        }
//                                    }
//
//                                    @Override
//                                    public void onError(Throwable t) {
//                                        Log.e(TAG, "Error calling the API.", t);
//                                        try {
//                                            stream.close();
//                                        } catch (IOException e) {
//                                            e.printStackTrace();
//                                        }
//                                    }
//
//                                    @Override
//                                    public void onCompleted() {
//                                        Log.i(TAG, "API completed.");
//                                        try {
//                                            stream.close();
//                                        } catch (IOException e) {
//                                            e.printStackTrace();
//                                        }
//                                    }
//                                });
//
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                        Log.e(TAG, "Error loading the input", e);
//                    }
//                }
//
//            }
//        }.start();
//
//    }
//
//}
